package com.sds.ai.impl.provider;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.sds.ai.impl.data.learn.Response;
import org.aitools.programd.Core;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;


import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Random;

@Singleton
public class AIMLResponseProvider {

    private static String DEFAULT_BOT = "Kim";


    private static String OLD_MESSAGE_KEY = "OLD_MESSAGE";
    private static String OLD_MESSAGE_KEY_2 = "OLD_MESSAGE_2";
    private static String STATE_KEY = "STATE";
    private static String WAIT_FOR_NEW_RESPONSE = "WAIT FOR NEW RESPONSE";
    private static String WAIT_FOR_UPDATE_RESPONSE = "WAIT FOR UPDATE RESPONSE";
    private static List<String> defaultAskForNewPattern;
    private static List<String> defaultGotNewResponse;
    private static List<String> defaultUpdateResponse;

    static {
        try {
            defaultAskForNewPattern = IOUtils.readLines(AIMLResponseProvider.class.getResourceAsStream("defaultAskForNewPattern.txt"), "UTF-8");
            defaultGotNewResponse = IOUtils.readLines(AIMLResponseProvider.class.getResourceAsStream("defaultNewResponse.txt"), "UTF-8");
            defaultUpdateResponse = IOUtils.readLines(AIMLResponseProvider.class.getResourceAsStream("defaultUpdateResponse.txt"), "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private Core chatCore = null;
    private final Random random = new Random();
    private final DataProviderImpl dataProvider;


    @Inject
    public AIMLResponseProvider(DataProviderImpl dataProvider) {
        this.dataProvider = dataProvider;
    }

    public void setChatCore(Core chatCore) {
        this.chatCore = chatCore;

    }

    public boolean isReady() {
        return chatCore != null;
    }

    public String getResponse(Map<String, String> memory, String message) {
        if (!isReady()) {
            return "I'm not ready yet";
        } else {
            String mainResponse;

            if (memory.get(STATE_KEY) != null) {
                String newPattern;
                if (memory.get(STATE_KEY).equals(WAIT_FOR_NEW_RESPONSE)) {
                    newPattern = memory.get(OLD_MESSAGE_KEY);
                } else {
                    newPattern = memory.get(OLD_MESSAGE_KEY_2);
                }
                String newResponse = message;

                String responseMesssage = explodeData(getRandomString(defaultGotNewResponse), newPattern, message);
                Response response = new Response();
                response.setPattern(newPattern);
                response.setResponse(newResponse);

                boolean found = false;
                for (Response myResponse : dataProvider.getAll(Response.class)) {
                    if (StringUtils.equalsIgnoreCase(response.getPattern(), myResponse.getPattern())) {
                        myResponse.setResponse(newResponse);
                        dataProvider.update(myResponse);
                        found = true;
                    }
                }
                if (!found) {
                    dataProvider.getManagedInstance(response);
                }
                memory.remove(STATE_KEY);
                mainResponse = responseMesssage;
            } else {

                String response = "";

                for (Response myResponse : dataProvider.getAll(Response.class)) {
                    if (StringUtils.equalsIgnoreCase(message, myResponse.getPattern())) {
                        response = myResponse.getResponse();
                    }
                }
                if (response.length() > 0) {
                    mainResponse = response;
                } else {
                    response = chatCore.getResponse(message, chatCore.getHostname(), DEFAULT_BOT);
                    if (response.length() > 0 && !response.equals("GET_NEW_ANSWER")) {
                        mainResponse = response;
                    } else if (response.equals("GET_NEW_ANSWER")) {
                        memory.put(STATE_KEY, WAIT_FOR_UPDATE_RESPONSE);
                        mainResponse = explodeData(getRandomString(defaultUpdateResponse), memory.get(OLD_MESSAGE_KEY));
                    } else {
                        memory.put(STATE_KEY, WAIT_FOR_NEW_RESPONSE);
                        mainResponse = explodeData(getRandomString(defaultAskForNewPattern), message);
                    }
                }
            }
            memory.put(OLD_MESSAGE_KEY_2, memory.get(OLD_MESSAGE_KEY));
            memory.put(OLD_MESSAGE_KEY, message);
            return mainResponse;
        }

    }


    private String explodeData(String message, String oldMessage) {
        return message.replace("[OLD_MESSAGE]", oldMessage);
    }

    private String explodeData(String message, String oldMessage, String newResponse) {
        return message.replace("[OLD_MESSAGE]", oldMessage).replace("[NEW_RESPONSE]", newResponse);
    }

    private String getRandomString(List<String> strings) {
        return strings.get(random.nextInt(strings.size()));
    }

}

